package cn.source.web.controller.tool;

import cn.hutool.core.util.StrUtil;
import cn.source.common.core.domain.AjaxResult;
import cn.source.system.domain.BuzMember;
import cn.source.system.domain.VipOrderModel;
import cn.source.system.domain.VipPrice;
import cn.source.system.domain.dto.VipPayDto;
import cn.source.enums.CommPayEnum;
import cn.source.enums.PayTypeEnum;
import cn.source.system.service.*;
import cn.source.util.WxV3PayUtil;
import com.alibaba.fastjson.JSONObject;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author tubo
 * @date 2024/06/13
 */
@RestController
@Slf4j
public class PayController {

    @Resource
    private PayService payService;

    @Resource
    private IVipOrderService vipOrderService;

    @Resource
    private IVipService vipService;

    @Autowired
    private IBuzMemberService buzMemberService;

    @Resource
    IVipPriceService vipPriceService;


    /**
     * 判断是否含有特殊字符
     *
     * @param str
     * @return true为包含，false为不包含
     */
    public static boolean isSpecialChar(String str) {
        String regEx = "[ _`~!#$%^&*()+=|{}&':;',\\[\\]<>/?~！#￥%……&*（）——+|{}【】‘；：”“’。，、？]|\n|\r|\t";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.find();
    }


    //效验
    protected static boolean sqlValidate(String str) {
        str = str.toLowerCase();//统一转为小写
        String badStr = "'|select|update|and|or|delete|insert|truncate|char|into"
                + "|substr|declare|exec|master|drop|execute|sleep|"
                + "union|;|--|+|,|like|//|/|%|#|*|$|\"|http|cr|lf|<|>|(|)";//过滤掉的sql关键字，可以手动添加
        String[] badStrs = badStr.split("\\|");
        for (int i = 0; i < badStrs.length; i++) {
            if (str.indexOf(badStrs[i]) >= 0) {
                return true;
            }
        }
        return false;
    }

    @PostMapping("/api/user/vip-pay")
    public AjaxResult vipPay(@RequestBody @Validated VipPayDto vipPayDto) {

        if(vipPayDto.getUserId() == null){
            return AjaxResult.error("请先登录");
        }
        if (isSpecialChar(vipPayDto.getUserId().toString()) || sqlValidate(vipPayDto.getUserId().toString())) {
            AjaxResult.error("参数包含非法字符");
        }

        if(vipPayDto.getPriceClass() == null){
            return AjaxResult.error("价格类型不能为空");
        }
        if (isSpecialChar(vipPayDto.getPriceClass().toString()) || sqlValidate(vipPayDto.getPriceClass().toString())) {
            AjaxResult.error("参数包含非法字符");
        }

        if(vipPayDto.getVipPrice() == null){
            return AjaxResult.error("金额不能为空");
        }
        if (isSpecialChar(vipPayDto.getVipPrice().toString()) || sqlValidate(vipPayDto.getVipPrice().toString())) {
            AjaxResult.error("参数包含非法字符");
        }
        if(!vipPayDto.getVipPrice().matches("\\d+")){
            AjaxResult.error("请输入正整数");
        }

        int price=new BigDecimal(vipPayDto.getVipPrice()).intValue();
        if(price<1){
            AjaxResult.error("金额与价格不符，请核对后再支付");
        }

        VipPrice vipPrice=new VipPrice();
        vipPrice.setPriceClass(vipPayDto.getPriceClass());
        List<VipPrice> list=vipPriceService.selectVipPriceList(vipPrice);

        if(list!=null&&list.size()>0){
            vipPrice=list.get(0);
        }
        boolean priceRight=false;

        if(vipPrice.getPrice1()!=null){
            int price1=vipPrice.getPrice1().intValue();
            if(price==price1){
                priceRight=true;
            }
        }

        if(vipPrice.getPrice2()!=null){
            int price1=vipPrice.getPrice2().intValue();
            if(price==price1){
                priceRight=true;
            }
        }

        if(vipPrice.getPrice3()!=null){
            int price1=vipPrice.getPrice3().intValue();
            if(price==price1){
                priceRight=true;
            }
        }

        if(vipPrice.getPrice4()!=null){
            int price1=vipPrice.getPrice4().intValue();
            if(price==price1){
                priceRight=true;
            }
        }

        if(!priceRight){
            AjaxResult.error("金额与价格不符，请核对后再支付");
        }

        vipPayDto.setVipId(vipPrice.getId());

        //固定写实这个支付方式，不管是h5还是小程序，都用这种方式
        return AjaxResult.success(payService.vipPay(PayTypeEnum.getPayType("WXMpPay"),vipPayDto));
        //return AjaxResult.success(payService.vipPay(PayTypeEnum.getPayType(vipPayDto.getPayType()),vipPayDto));
    }

    @GetMapping("/api/user/vip-pay4web/{payType}")
    public AjaxResult vipPay(@PathVariable("payType") String payType, String userId,String priceClass,String price, HttpServletRequest request) {

        if(userId == null){
            return AjaxResult.error("请先登录");
        }
        if (isSpecialChar(userId) || sqlValidate(userId)) {
            AjaxResult.error("参数包含非法字符");
        }

        if(priceClass == null){
            return AjaxResult.error("价格类型不能为空");
        }
        if (isSpecialChar(priceClass) || sqlValidate(priceClass)) {
            AjaxResult.error("参数包含非法字符");
        }

        if(price == null){
            return AjaxResult.error("金额不能为空");
        }
        if (isSpecialChar(price) || sqlValidate(price)) {
            AjaxResult.error("参数包含非法字符");
        }
        if(!price.matches("\\d+")){
            AjaxResult.error("请输入正整数");
        }

        int priceVal=new BigDecimal(price).intValue();
        if(priceVal<1){
            AjaxResult.error("金额与价格不符，请核对后再支付");
        }

        VipPrice vipPrice=new VipPrice();
        vipPrice.setPriceClass(priceClass);
        List<VipPrice> list=vipPriceService.selectVipPriceList(vipPrice);

        if(list!=null&&list.size()>0){
            vipPrice=list.get(0);
        }
        boolean priceRight=false;

        if(vipPrice.getPrice1()!=null){
            int price1=vipPrice.getPrice1().intValue();
            if(priceVal==price1){
                priceRight=true;
            }
        }

        if(vipPrice.getPrice2()!=null){
            int price1=vipPrice.getPrice2().intValue();
            if(priceVal==price1){
                priceRight=true;
            }
        }

        if(vipPrice.getPrice3()!=null){
            int price1=vipPrice.getPrice3().intValue();
            if(priceVal==price1){
                priceRight=true;
            }
        }

        if(vipPrice.getPrice4()!=null){
            int price1=vipPrice.getPrice4().intValue();
            if(priceVal==price1){
                priceRight=true;
            }
        }

        if(!priceRight){
            AjaxResult.error("金额与价格不符，请核对后再支付");
        }

        VipPayDto vipPayDto=new VipPayDto();
        vipPayDto.setUserId(userId);
        vipPayDto.setPriceClass(priceClass);
        vipPayDto.setVipPrice(price);
        vipPayDto.setClientIP(request.getRemoteAddr());

        //固定写实这个支付方式，不管是h5还是小程序，都用这种方式
        return AjaxResult.success(payService.vipPay4web(PayTypeEnum.getPayType(payType),vipPayDto));
        //return AjaxResult.success(payService.vipPay(PayTypeEnum.getPayType(vipPayDto.getPayType()),vipPayDto));
    }

    @GetMapping("/api/user/checkOpenid")
    public AjaxResult checkOpenid(String userId) {
        if(StrUtil.isEmpty(userId)) {
            return AjaxResult.error("请先登录");
        }
        if (isSpecialChar(userId.toString()) || sqlValidate(userId.toString())) {
            AjaxResult.error("参数包含非法字符");
        }
        BuzMember member= buzMemberService.selectBuzMemberById(userId);
        if(member==null){
            return AjaxResult.error("用户不存在");
        }else{
            String openid=member.getOpenid();
            Map map=new HashMap();
            if(StrUtil.isEmpty(openid)) {
                map.put("openid",false);
            }else{
                map.put("openid",true);
            }
            return AjaxResult.success(map);
        }

    }


    /**
     * vip下单异步回调
     * @param payType
     * @param httpServletRequest
     * @param httpServletResponse
     * @return
     */
    @PostMapping("/api/pay/wxPayVipNotifyUrl/{payType}")
    public Object wxPayVipPayNotifyUrl(@PathVariable("payType") String payType, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        CommPayEnum payTypeEnum = CommPayEnum.getPayType(payType);
        log.info("收到平台Vip下单异步通知");
        // 构造 RequestParam
        String orderNo;
        String successTime;
        String transactionId="";
        if (CommPayEnum.WX_JS_PAY.equals(payTypeEnum)) {
            Transaction decryptObject = WxV3PayUtil.jsPayCheckSign(httpServletRequest);
            if (decryptObject == null) {
                return WxV3PayUtil.notice(false, httpServletResponse);
            }
            orderNo = decryptObject.getOutTradeNo();
        } else if (CommPayEnum.WX_H5_PAY.equals(payTypeEnum)){
            Transaction decryptObject = WxV3PayUtil.jsPayCheckSign(httpServletRequest);
            if (decryptObject == null) {
                return WxV3PayUtil.notice(false, httpServletResponse);
            }
            orderNo = decryptObject.getOutTradeNo();
        }
        else {
            com.wechat.pay.java.service.partnerpayments.app.model.Transaction decryptObject = WxV3PayUtil.appPayCheckSign(httpServletRequest);
            if (decryptObject == null) {
                return WxV3PayUtil.notice(false, httpServletResponse);
            }
            orderNo = decryptObject.getOutTradeNo();
        }

        //如果没有更新就更新数据库及插入vip信息
        VipOrderModel vipOrderModel = vipOrderService.findOne(orderNo);
        if (vipOrderModel == null) {
            return WxV3PayUtil.notice(false, httpServletResponse);
        }
        vipService.confirmVipOrder(vipOrderModel.getId());
        return WxV3PayUtil.notice(true, httpServletResponse);
    }


    /**
     * 订单信息支付查询
     */
    @GetMapping("/api/pay/wxPayVipOrderStatus")
    public Object wxPayVipQuery( String orderSn, String userId, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        JSONObject result = new JSONObject();
        if (orderSn == null || orderSn.isEmpty()){
            return AjaxResult.error("参数缺失");
        }

        if (userId == null || userId.isEmpty()){
            return AjaxResult.error("参数缺失");
        }
        log.info("同步VIP订单查询");
        //如果没有更新就更新数据库及插入vip信息
        VipOrderModel vipOrderModel = vipOrderService.findOne(orderSn);
        if (vipOrderModel == null) {
            return AjaxResult.error("支付订单不存在");
        }
        // 不是待支付得都不进行查询
        if (!vipOrderModel.getStatus().equals(1)){
            result.put("status", vipOrderModel.getStatus());
            return AjaxResult.success(result);
        }
        // 不是当前用户不查询
        if (!vipOrderModel.getOwner().equals(userId)){
            return AjaxResult.error("支付订单不存在");
        }

        com.wechat.pay.java.service.payments.model.Transaction info = WxV3PayUtil.queryOrder(orderSn);
        if (info == null) {
            return AjaxResult.error("商户订单号不存在");
        }
        String tradeState = info.getTradeState().name();
        if (tradeState.equals("SUCCESS")) {
            // 支付成功
            result.put("status", 2);
            vipService.confirmVipOrder(vipOrderModel.getId());
            WxV3PayUtil.notice(true, httpServletResponse);
        }
        if (tradeState.equals("FAILED")) {
            result.put("status", 3);
        }
        if (tradeState.equals("NOTPAY")) {
            result.put("status", 1);
        }

        return AjaxResult.success("查询成功", result);
    }
}
